package org.poem.register;

import org.I0Itec.zkclient.exception.*;
import org.poem.config.IZkLockConfig;
import org.poem.exception.ZkRegisterException;
import org.poem.exception.enums.KeeperEnums;
import org.poem.zk.ZkParent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.management.ManagementFactory;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.List;

/**
 * zk的分布式注册
 */
public class ZkDistributedRegister extends ZkParent {

    private static final Logger logger = LoggerFactory.getLogger(ZkDistributedRegister.class);

    /**
     * 节点路径
     */
    private static final String BASE_PATH = "temp-node";
    /**
     * 节点路径
     */
    private String nodePath;
    /**
     * 节点信息
     */
    private String localAddress;

    /**
     * 初始化
     *
     * @param config
     */
    public ZkDistributedRegister(IZkLockConfig config) {
        super(config);
        initLockPath();
        String basePath = super.getConfig().getBasePath().replaceFirst("(.*)?/$", "$1");
        if (!super.getZkClient().exists(basePath)) {
            logger.info("主路径不存在,准备创建!{}", basePath);
            super.getZkClient().createPersistent(basePath, "true");
        }
        if (!super.getZkClient().exists(basePath + "/" + BASE_PATH)) {
            super.getZkClient().createPersistent(basePath + "/" + BASE_PATH, "true");
            logger.info("二级路径不存在,准备创建!{}", basePath + "/" + BASE_PATH);
        }
    }

    /**
     * 获取节点下的所有数据
     * @return 节点下的所有数据
     */
    public List<String> getNodeData(){
        String basePath = super.getConfig().getBasePath().replaceFirst("(.*)?/$", "$1");
        List<String> children = super.getZkClient().getChildren(basePath + "/" + BASE_PATH);
        return children;

    }
    /**
     * 注册地址
     */
    public void register() throws ZkRegisterException {
        //创建当前的零时节点
        try {
            super.getZkClient().createEphemeral(nodePath, localAddress);
        } catch (ZkInterruptedException e) {
            //被打断
            e.printStackTrace();
            throw new ZkRegisterException(e.getMessage());
        } catch (IllegalArgumentException e) {
            //参数不正确
            e.printStackTrace();
            throw new ZkRegisterException(e.getMessage());
        } catch (ZkException e) {
            e.printStackTrace();
            if (e instanceof ZkNoNodeException) {
                throw new ZkRegisterException(KeeperEnums.NO_NODE, nodePath + ",节点没有找到");
            } else if (e instanceof ZkBadVersionException) {
                throw new ZkRegisterException(KeeperEnums.ZK_BAD_VERSION, this.localAddress + ",版本不正确");
            } else if (e instanceof ZkNodeExistsException) {
                throw new ZkRegisterException(KeeperEnums.ZK_NODE_EXISTS, nodePath + "已存在");
            }
            throw new ZkRegisterException(e.getMessage());
        } catch (RuntimeException e) {
            e.printStackTrace();
            throw new ZkRegisterException(e.getMessage());
        }
    }

    /**
     * 取消注册
     */
    public void disRegister() {
        super.getZkClient().delete(nodePath);
    }

    /**
     * 初始化锁的路径
     */
    private void initLockPath() {
        if (super.getConfig().getBasePath() == null) {
            nodePath = "/";
        } else if (super.getConfig().getBasePath().endsWith("/")) {
            nodePath = super.getConfig().getBasePath();
        } else {
            nodePath = super.getConfig().getBasePath() + "/";
        }
        try {
            localAddress = InetAddress.getLocalHost().getHostAddress();
        } catch (UnknownHostException e) {
            localAddress = ManagementFactory.getRuntimeMXBean().getName().split("@")[1];
        }
        nodePath = nodePath + BASE_PATH + "/" + localAddress;
    }
}
